const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const devMode = process.env.NODE_ENV !== "production";
console.log("devMode", devMode);

const plugins = [
  new HtmlWebpackPlugin({
    template: path.resolve(__dirname, "index.html"),
    title: "App",
    filename: "index.html",
    hash: true,
    minify: {
      collapseWhitespace: true,
      keepClosingSlash: true,
      removeComments: true,
      removeRedundantAttributes: true,
      removeScriptTypeAttributes: true,
      removeStyleLinkTypeAttributes: true,
      useShortDoctype: true,

      // https://github.com/DanielRuf/html-minifier-terser 查看
      minifyCSS: true,
      minifyJS: true,
    },
  }),
  new webpack.DefinePlugin({
    NODE_ENV: JSON.stringify(process.env.NODE_ENV),
  }),
  new CopyWebpackPlugin({
    patterns: [
      {
        // 把不需要经过 webpack 处理的资源从（from）拷贝到 （to）目录下
        from: path.resolve(__dirname, "./public"),
        to: path.resolve(__dirname, "./dist"),
      },
    ], // . 默认打包设置的 dist 目录
  }),
];

if (!devMode) {
  plugins.push(
    new MiniCssExtractPlugin({
      filename: devMode ? "[name].css" : "[name].[contenthash:8].css",
      chunkFilename: devMode ? "[id].css" : "[id].[contenthash:8].css",
    })
  );
}
if (devMode) {
  plugins.push(new webpack.HotModuleReplacementPlugin());
}

const webpackConfig = {
  mode: process.env.NODE_ENV,
  entry: {
    index: "./src/main.js",
  },
  output: {
    path: path.resolve(__dirname, "./dist"),

    filename: devMode ? "[name].js" : "[name].[contenthash:8].js",
    chunkFilename: devMode ? "[id].js" : "[id].[contenthash:8].js",

    publicPath: devMode ? "" : "./", // html 模板文件中的资源前缀

    assetModuleFilename: "images/[hash][ext][query]", // 全局一些资源的引用路径名

    clean: true, // 5.20.0+
  },
  resolve: {
    alias: {
      "@": path.resolve("src"),
    },
  },
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          devMode ? "style-loader" : MiniCssExtractPlugin.loader,
          // "css-loader",
          {
            loader: "css-loader",
            options: {
              url: true, // 处理引用资源的地址，会重命名资源名，图片
              import: true, // 是否处理CSS代码中的 import
              modules: false, // css 的模块化处理，会重命名类名，使用时候，通过 js 引用 css 文件，返回一个对象 import stryles from "./index.css"
              sourceMap: false,
              esModule: false, // 主要是给 css-loader 处理后返回 {default: ...} 或 []
              importLoaders: 0, // 指定样式文件从后向前的第一个 loader 开始处理当前的样式文件，比如这里如果是 1，那么不用经过 sass-loader 处理，直接通过 postcss-loader 开始处理，如果是 2, 那么就不用经过 sass-loader 和 postcss-loader 处理，直接通过 css-loader 开始处理
            },
          },
          "postcss-loader",
          "sass-loader",
        ],
      },

      {
        test: /\.png$/,
        type: "asset/resource", // 相当与 file-loader，处理成一个文件输出到对应的目录中,会修改资源的名

        generator: {
          // 会覆盖 output.assetModuleFilename 设置的路径名
          filename: "images/[hash][ext][query]",
        },
      },
      {
        test: /\.ico$/i,
        type: "asset/inline", // 相当于 url-loader,可以把文件内容处理成 base64 内联到 html 文件中
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf|frag|txt)$/i,
        type: "asset/source", // 相当于 raw-loader，输出字符串，对内容不做任何转换, 直接使用 url 路径引入
        generator: {
          // 会覆盖 output.assetModuleFilename 设置的路径名
          filename: "font/[hash][ext][query]",
        },
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: "asset",
        parser: {
          dataUrlCondition: {
            // 内联条件，如果文件体积大于 maxSize 处理成文件,重命名资源名，如果小于 maxSize 就处理成 base64
            maxSize: 10 * 1024, // 10kb
          },
        },
      },
      // html 中的资源处理, 比如 image
      {
        test: /\.html/i,
        loader: "html-loader",
      },
    ],
  },
  plugins,
};

if (devMode) {
  webpackConfig.devServer = {
    static: {
      directory: path.resolve(__dirname, "./public"),
    },
    compress: false,
    port: 9000,
    open: true,
  };
}

module.exports = webpackConfig;

/*
// 注意：
//   如果源码中通过一些 @ 或者其他引入资源，那么是自己配置的 resolve.alias.
//   如果源码中通过 ～ 引入资源，那么在就是引入 node_modules 下的资源
 */
